import java.util.ArrayList;

public class FileSystem {
	private static FileSystem onlyFileSystem = new FileSystem();
	private Directory currentdir, root;

	public static FileSystem getInstance() {
		return onlyFileSystem;
	}

	private FileSystem() {
		root = new Directory("", null);
		currentdir = root;
	}

	public Directory getCurrentdir() {
		return currentdir;
	}

	// Return the full path of any SytemItem object as a string.
	public String getItemPath(SystemItem item) {
		if (item.getParent() != null)
			return item.getFullPath();
		else
			return "/";
	}

	// Parse a path like /user/this into an arraylist
	public ArrayList<String> parsePath(String path) {
		String[] pathArray = path.split("/");
		ArrayList<String> pathArrayList = new ArrayList<String>();
		for (String p : pathArray) {
			if (!p.equals(""))
				pathArrayList.add(p);
		}
		return pathArrayList;
	}

	// Return a systemItem, given an array path + char indicating if 
	// search should start at root, or at currentdir.
	public SystemItem getItem(ArrayList<String> patharray, String firstchar)
			throws InvalidPathException {
		Directory starthere;
		if (firstchar.equals("/"))
			starthere = root;
		else
			starthere = currentdir;
		for (int i = 0; i < patharray.size() - 1; i++) {
			if (starthere.getContents().get(patharray.get(i)).getClass()
					.getName() != "Directory") {
				throw new InvalidPathException("Sorry, invalid path");
			}
			starthere = (Directory) starthere.getContents().get(
					patharray.get(i));
		}
		try {
			SystemItem returnvalue = starthere.getContents().get(
					patharray.get(patharray.size() - 1));
			if (returnvalue == null)
				throw new InvalidPathException(
						"Sorry, item does not exist at this path");
			return returnvalue;
		} catch (ArrayIndexOutOfBoundsException e) {
			return starthere;
		}
	}

	// Return systemitem given its path as provided by user.
	public SystemItem getItem(String path) throws InvalidPathException {
		String firstchar = path.substring(0, 1);
		ArrayList<String> patharray = parsePath(path);
		return getItem(patharray, firstchar);
	}

	// Return Directory of item's parent, when given item's path.
	// this is useful for commands like MKDIR, when the path user provides
	// includes at the end, a non-existing systemitem that must be created.
	public Directory getItemParent(String path) throws InvalidPathException {
		String firstchar = path.substring(0, 1);
		ArrayList<String> patharray = parsePath(path);
		patharray.remove(patharray.size() - 1);
		return (Directory) getItem(patharray, firstchar);
	}

	// When given a path, like in mkdir, will return the name
	// of new item to make. Also useful for when user 
	// tries to make new Files.
	public String getItemName(String path) throws InvalidPathException {
		ArrayList<String> parsedPath = parsePath(path);
		try {
			return parsedPath.get(parsedPath.size() - 1);
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new InvalidPathException(
					"Sorry. Please enter a valid name for new directory.");
		}
	}
}
